package com.hx.springboot1.config;


import com.hx.springboot1.security.MyLoginSuccessHandler;
import com.hx.springboot1.security.MyLogoutSuccessHandler;
import com.hx.springboot1.security.MyUserDetailsService;
import com.hx.springboot1.security.VerifyFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/*    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;
    @Autowired
    private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource;*/
    @Autowired
    private MyUserDetailsService userDetailsService;
    @Autowired
    private DataSource dataSource;
    @Autowired
    private MyLogoutSuccessHandler logoutSuccessHandler;
    @Autowired
    private MyLoginSuccessHandler loginSuccessHandler;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/changeLanguage/**","/getVerifyCode/**").permitAll()
                .anyRequest().authenticated()
                .and().formLogin()
                .loginPage("/loginPage")
                //.loginProcessingUrl("/loginRequest")
                /* 在配置了loginPage之后，loginProcessingUrl如果没配置，默认就是loginPage("url")的url，因此 form登入的action就等于这个 url */
                /* 如果loginPage没有配置，那么 默认的url为 login */
                /*.defaultSuccessUrl("/index")        因为自定义了成功处理器，处理器里重定向了登入成功的页面，所以可以注释掉了  如果没有定义认证成功处理器，则要配置defaultSuccessUrl*/
                .failureUrl("/login/error").permitAll()
                .successHandler(loginSuccessHandler)
                /*.authenticationDetailsSource(authenticationDetailsSource)*/    // 使用自定义登入成功处理器  自定义登录处理器作用：就是在登入成功的时候 打印一下log
                .and().addFilterBefore(new VerifyFilter(), UsernamePasswordAuthenticationFilter.class).logout()     /*  .logoutSuccessUrl("/logoutSuccess")*/
                // 默认的logoutUrl为:logout，和登入一样，如果没配置 logoutUrl  那么默认的url为 logout(用于登出的action)
                //  如果配置了 logoutUrl，而没配置logoutSuccessUrl，  那么 logoutSuccessUrl的 url就 默认为 logoutUrl配置的 url值
                .deleteCookies("JSESSIONID")
                .logoutSuccessHandler(logoutSuccessHandler).permitAll()  // 使用自定义的 logoutSuccessHandler
                .and().rememberMe()
                .tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(60*1000*60)
                .userDetailsService(userDetailsService)
                .and().csrf().disable();/*.ignoringAntMatchers("/druid/*") // csrf 导致 druid后台监控 login无反应;
                .ignoringAntMatchers("/swagger-ui/*");*/
    }

    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        // 首次启动时 自动创建 表  用于存储 token和username的对应关系
        // tokenRepository.setCreateTableOnStartup(true);
        return tokenRepository;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder())
                /*.and().authenticationProvider(customAuthenticationProvider)*/;
    }
    
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/img/**","/css/**", "/js/**","/druid/**");  // 对资源放行
    }
}
